glcontext: Make begin/end_draw() paired
authorBenjamin Otte <otte@redhat.com>
Wed, 23 Nov 2016 04:18:43 +0000 (05:18 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 5 Dec 2016 14:02:47 +0000 (15:02 +0100)
This way, we can query the GL context's state via
gdk_gl_context_is_drawing().

Use this function to make GL contexts as attached and grant them access
to the front/backbuffer for rendering.

All of this is still unused because GL drawing is still disabled.

gdk/gdkglcontext.c
gdk/gdkglcontextprivate.h
gdk/gdkwindow.c
gdk/mir/gdkmirdisplay.c
gdk/wayland/gdkglcontext-wayland.c
gdk/x11/gdkglcontext-x11.c
gdk/x11/gdkglcontext-x11.h

index 14157db0571b4954b985fe67bc115220557464d9..2717f5d92925ac00e3f23be85afdb6cea0800e68 100644 (file)
@@ -97,6 +97,7 @@ typedef struct {
   int gl_version;
 
   guint realized : 1;
+  guint is_drawing : 1;
   guint use_texture_rectangle : 1;
   guint has_gl_framebuffer_blit : 1;
   guint has_frame_terminator : 1;
@@ -368,6 +369,78 @@ gdk_gl_context_init (GdkGLContext *self)
   priv->use_es = -1;
 }
 
+/*< private >
+ * gdk_gl_context_is_drawing:
+ * @context: a #GdkGLContext
+ *
+ * Returns %TRUE if @context is in the process of drawing to its window. In such
+ * cases, it will have access to the window's backbuffer to render the new frame
+ * onto it.
+ *
+ * Returns: %TRUE if the context is between begin_frame() and end_frame() calls.
+ *
+ * Since: 3.90
+ */
+gboolean
+gdk_gl_context_is_drawing (GdkGLContext *context)
+{
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+  return priv->is_drawing;
+}
+
+/*< private >
+ * gdk_gl_context_begin_frame:
+ * @context: a #GdkGLContext
+ * @region: (inout): The clip region that needs to be repainted
+ *
+ * Sets up @context and @drawing for a new drawing.
+ *
+ * The @context is free to update @region to the size that actually needs to
+ * be repainted. Contexts that do not support partial blits for example may
+ * want to invalidate the whole window instead.
+ *
+ * The function does not clear the background. Clearing the backgroud is the
+ * job of the renderer. The contents of the backbuffer are undefined after this
+ * function call.
+ *
+ * Since: 3.90
+ */
+void
+gdk_gl_context_begin_frame (GdkGLContext   *context,
+                            cairo_region_t *region)
+{
+  GdkGLContextPrivate *priv, *shared_priv;
+  GdkGLContext *shared;
+  int ww, wh;
+
+  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
+  g_return_if_fail (region != NULL);
+
+  priv = gdk_gl_context_get_instance_private (context);
+  priv->is_drawing = TRUE;
+
+  shared = gdk_gl_context_get_shared_context (context);
+  shared_priv = gdk_gl_context_get_instance_private (shared);
+  shared_priv->is_drawing = TRUE;
+
+  GDK_GL_CONTEXT_GET_CLASS (context)->begin_frame (context, region);
+
+  ww = gdk_window_get_width (priv->window) * gdk_window_get_scale_factor (priv->window);
+  wh = gdk_window_get_height (priv->window) * gdk_window_get_scale_factor (priv->window);
+
+  gdk_gl_context_make_current (shared);
+
+  /* Initial setup */
+  glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
+  glDisable (GL_DEPTH_TEST);
+  glDisable (GL_BLEND);
+  glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+  glViewport (0, 0, ww, wh);
+
+}
+
 /*< private >
  * gdk_gl_context_end_frame:
  * @context: a #GdkGLContext
@@ -387,15 +460,24 @@ gdk_gl_context_end_frame (GdkGLContext   *context,
                           cairo_region_t *painted,
                           cairo_region_t *damage)
 {
+  GdkGLContextPrivate *priv, *shared_priv;
+  GdkGLContext *shared;
+
   g_return_if_fail (GDK_IS_GL_CONTEXT (context));
 
   GDK_GL_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage);
+
+  priv = gdk_gl_context_get_instance_private (context);
+  priv->is_drawing = FALSE;
+
+  shared = gdk_gl_context_get_shared_context (context);
+  shared_priv = gdk_gl_context_get_instance_private (shared);
+  shared_priv->is_drawing = FALSE;
 }
 
 GdkGLContextPaintData *
 gdk_gl_context_get_paint_data (GdkGLContext *context)
 {
-
   GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
 
   if (priv->paint_data == NULL)
index 24fd80ead3cff4997e42365fa27efd97e2fb8f86..3193e2d0d8e2868e933ffd54be6b99339aeca3fd 100644 (file)
@@ -89,6 +89,9 @@ gboolean                gdk_gl_context_use_texture_rectangle    (GdkGLContext
 gboolean                gdk_gl_context_has_framebuffer_blit     (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_frame_terminator     (GdkGLContext    *context);
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
+gboolean                gdk_gl_context_is_drawing               (GdkGLContext    *context);
+void                    gdk_gl_context_begin_frame              (GdkGLContext    *context,
+                                                                 cairo_region_t  *region);
 void                    gdk_gl_context_end_frame                (GdkGLContext    *context,
                                                                  cairo_region_t  *painted,
                                                                  cairo_region_t  *damage);
index f79cf4b2a7056b50087ca5d671cee453fb457baf..d7e1d04ec8797557904d57521349f4ff6c91623c 100644 (file)
@@ -2715,40 +2715,6 @@ gdk_window_begin_paint_internal (GdkWindow            *window,
 
   surface_content = gdk_window_get_content (window);
 
-#if 0
-  if (window->current_paint.use_gl)
-    {
-      GdkGLContext *context;
-
-      int ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window);
-      int wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window);
-
-      context = gdk_window_get_paint_gl_context (window, NULL);
-      if (context == NULL)
-        {
-          g_warning ("gl rendering failed, context: %p", context);
-          window->current_paint.use_gl = FALSE;
-        }
-      else
-        {
-         gdk_gl_context_make_current (context);
-          /* With gl we always need a surface to combine the gl
-             drawing with the native drawing. */
-          needs_surface = TRUE;
-          /* Also, we need the surface to include alpha */
-          surface_content = CAIRO_CONTENT_COLOR_ALPHA;
-
-          /* Initial setup */
-          glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
-          glDisable (GL_DEPTH_TEST);
-          glDisable(GL_BLEND);
-          glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
-          glViewport (0, 0, ww, wh);
-        }
-    }
-#endif
-
   if (needs_surface)
     {
       window->current_paint.surface = gdk_window_create_similar_surface (window,
@@ -2797,31 +2763,6 @@ gdk_window_end_paint_internal (GdkWindow *window)
     {
       cairo_surface_t *surface;
 
-#if 0
-      if (window->current_paint.use_gl)
-        {
-          cairo_region_t *opaque_region = cairo_region_copy (window->current_paint.region);
-
-          gdk_gl_context_make_current (window->gl_paint_context);
-
-          if (!cairo_region_is_empty (opaque_region))
-            gdk_gl_texture_from_surface (window->current_paint.surface,
-                                         opaque_region);
-          if (!cairo_region_is_empty (window->current_paint.need_blend_region))
-            {
-              glEnable(GL_BLEND);
-              gdk_gl_texture_from_surface (window->current_paint.surface,
-                                           window->current_paint.need_blend_region);
-              glDisable(GL_BLEND);
-            }
-
-          cairo_region_destroy (opaque_region);
-
-          gdk_gl_context_end_frame (window->gl_paint_context,
-                                    window->current_paint.region,
-                                    window->active_update_area);
-        }
-#endif
       surface = gdk_window_ref_impl_surface (window);
       cr = cairo_create (surface);
 
index 0427dc3823170665bd5e2cdde97e548289111436..d5c4cd5f82057316bece7f0b1fa17bc7bab5d1db 100644 (file)
@@ -631,7 +631,7 @@ gdk_mir_display_make_gl_context_current (GdkDisplay   *display,
   mir_context = GDK_MIR_GL_CONTEXT (context);
   window = gdk_gl_context_get_window (context);
 
-  if (mir_context->is_attached)
+  if (mir_context->is_attached || gdk_gl_context_is_drawing (context))
     {
       egl_surface = _gdk_mir_window_get_egl_surface (window,
                                                      mir_context->egl_config);
index c55e3070eb7ab0de4fc6f7d64eb4040131458ad4..1763ec7a18b95a5ea96d0394ec88b94486a51301 100644 (file)
@@ -464,7 +464,7 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay   *display,
   context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
   window = gdk_gl_context_get_window (context);
 
-  if (context_wayland->is_attached)
+  if (context_wayland->is_attached || gdk_gl_context_is_drawing (context))
     egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config);
   else
     {
index 16ebb423ac55530c17d3ad4932290275202a4488..92aaaf16adfbe5347a0317b9ce626e3e8de278df 100644 (file)
@@ -175,7 +175,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context,
 
   info = get_glx_drawable_info (window);
 
-  drawable = shared_x11->drawable;
+  drawable = shared_x11->attached_drawable;
 
   GDK_NOTE (OPENGL,
             g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s",
@@ -573,7 +573,6 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
   GdkX11Display *display_x11;
   GdkDisplay *display;
   GdkX11GLContext *context_x11;
-  GLXWindow drawable;
   XVisualInfo *xvisinfo;
   Display *dpy;
   DrawableInfo *info;
@@ -736,13 +735,10 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
 
   XFree (xvisinfo);
 
-  if (context_x11->is_attached)
-    drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_window_get_xid (window->impl_window);
-  else
-    drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
+  context_x11->attached_drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_window_get_xid (window->impl_window);
+  context_x11->unattached_drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
 
   context_x11->is_direct = glXIsDirect (dpy, context_x11->glx_context);
-  context_x11->drawable = drawable;
 
   GDK_NOTE (OPENGL,
             g_message ("Realized GLX context[%p], %s",
@@ -1248,6 +1244,7 @@ gdk_x11_display_make_gl_context_current (GdkDisplay   *display,
   GdkX11GLContext *context_x11;
   Display *dpy = gdk_x11_display_get_xdisplay (display);
   gboolean do_frame_sync = FALSE;
+  GLXWindow drawable;
 
   if (context == NULL)
     {
@@ -1263,11 +1260,16 @@ gdk_x11_display_make_gl_context_current (GdkDisplay   *display,
       return FALSE;
     }
 
+  if (context_x11->is_attached || gdk_gl_context_is_drawing (context))
+    drawable = context_x11->attached_drawable;
+  else
+    drawable = context_x11->unattached_drawable;
+
   GDK_NOTE (OPENGL,
-            g_message ("Making GLX context current to drawable %lu",
-                       (unsigned long) context_x11->drawable));
+            g_message ("Making GLX context %p current to drawable %lu",
+                       context, (unsigned long) drawable));
 
-  if (!glXMakeContextCurrent (dpy, context_x11->drawable, context_x11->drawable,
+  if (!glXMakeContextCurrent (dpy, drawable, drawable,
                               context_x11->glx_context))
     {
       GDK_NOTE (OPENGL,
index c00834fa1d2a5673f080a9f175a291a41e4e12b5..192ee9e21fb825ceb591ef2c2f10b2ae6672e095 100644 (file)
@@ -42,7 +42,8 @@ struct _GdkX11GLContext
 
   GLXContext glx_context;
   GLXFBConfig glx_config;
-  GLXDrawable drawable;
+  GLXDrawable attached_drawable;
+  GLXDrawable unattached_drawable;
 
   guint is_attached : 1;
   guint is_direct : 1;